package org.flycloud.web.sso.server;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.flycloud.web.sso.common.ILoginService;
import org.flycloud.web.sso.common.SessionCache;
import org.flycloud.web.sso.common.Token;
import org.flycloud.web.sso.common.UserSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class ServerController {

	@Value("${sso.server.view.logout}")
	private String logout;

	@Value("${sso.server.view.login}")
	private String login;

	@Value("${sso.server.url.index}")
	private String index;

	@Autowired
	private SessionCache sessions;

	@Autowired
	private ILoginService userInfoService;

	private static String getUrl(String url, HttpServletRequest request) {
		try {
			return URLDecoder.decode(request.getParameter(url), "UTF8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return null;
	}

	private String appendParam(String url, String key, String value) {
		if (url.contains("?")) {
			return url + "&" + key + "=" + value;
		} else {
			return url + "?" + key + "=" + value;
		}
	}

	@SuppressWarnings("unchecked")
	private synchronized static void saveLogoutUrl(HttpServletRequest request) {
		String logout = getUrl("logout", request);
		Map<String, Object> urls = null;
		urls = (Map<String, Object>) request.getSession().getAttribute("urls");
		if (urls == null) {
			urls = new HashMap<>();
			request.getSession().setAttribute("urls", urls);
		}
		System.out.println("收到：" + logout);
		urls.put(logout, logout);
	}

	@SuppressWarnings("unchecked")
	private synchronized static String getLogoutUrl(HttpServletRequest request) {
		Map<String, Object> urls = null;
		urls = (Map<String, Object>) request.getSession().getAttribute("urls");
		if (urls == null) {
			return null;
		} else {
			for (String key : urls.keySet()) {
				System.out.println("登出：" + key);
				return (String) urls.remove(key);
			}
			return null;
		}
	}

	/**
	 * 得到令牌
	 * 
	 * @return
	 */
	@RequestMapping("/sso")
	public ModelAndView token(HttpServletRequest request, HttpServletResponse response) {
		String target = getUrl("url", request);
		saveLogoutUrl(request);
		String token = (String) request.getSession().getAttribute(Token.TOKEN);
		if (token != null) {
			try {
				response.sendRedirect(appendParam(target, Token.TOKEN, token));
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		ModelAndView mv = new ModelAndView();
		mv.setViewName(this.login);
		mv.addObject("target", target);
		return mv;
	}

	@RequestMapping("/sso/si")
	public void login(HttpServletRequest request, HttpServletResponse response) {
		String target = request.getParameter("target");
		String username = request.getParameter("username");
		String password = request.getParameter("password");

		if (target == null || target.equals("")) {
			target = this.index;
		}

		UserSession us = userInfoService.login(username, password);

		String token = UUID.randomUUID().toString();
		sessions.setToken(token, us);
		request.getSession().setAttribute(Token.TOKEN, token);

		try {
			response.sendRedirect(appendParam(target, Token.TOKEN, token));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	@RequestMapping("/sso/so")
	public String logout(HttpServletRequest request, HttpServletResponse response) {
		try {
			String url = getLogoutUrl(request);
			if (url == null) {
				request.getSession().removeAttribute(Token.TOKEN);
				return this.logout;
			} else {
				response.sendRedirect(url);
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return this.logout;
	}

}